﻿using ScottPlot.Colormaps;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;
using static SkiaSharp.HarfBuzz.SKShaper;
using static System.Runtime.InteropServices.JavaScript.JSType;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace DetectScars.common
{
    class SocketUtils
    {
        //创建一个Socket客户端
        static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        static string ip = "192.168.1.250";
        static int port = 1001;
        private static bool isRunning = true;
        private static bool isFirst = true;
        private static int HEIGHT_VAL = 511;
        public static byte[] dataAORC;

        //传递数据到服务端
        public static string SendData(List<Connect> connects)
        {
            string msg = "";
            try
            {
                //if (socket.Connected)
                //{
                //    socket.Close();
                //}
                //检测socket是否连接
                //设置超时时间为10秒
                
                if (!socket.Connected)
                {
                    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    socket.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
                    socket.ReceiveTimeout = 10000;
                }
                if (!socket.Connected)
                {
                    msg = "未连接到socket服务端，请检查是否启动";
                    return msg;
                }
                if (isFirst)
                {
                    isRunning = true;
                    isFirst = false;
                    Thread receiveThread = new Thread(ReceiveData);
                    receiveThread.Start();
                    
                }
                //发送基础数据
                int status = 0;
                List<ushort> channels = AcqData.channels;
                foreach(ushort channel in channels)
                {
                    Connect connect = connects[channel];
                    connect.U2_ChannelNum = channel;
                    connect.U6_PulseWidth = 23;
                    status = socket.Send(connect.getConnect());
                }
                
                //if (isFirst)
                //{
                //    status = socket.Send(Connect.getIo());
                //    isFirst = false;
                //}
            }
            catch (Exception e)
            {
                LogUtils.WriteLog(e.Message);
                MessageBox.Show("连接主机异常："+e.Message);
                msg = e.Message;
            }
            return msg;

        }

        //传递数据到服务端
        public static string SendDataOne(Connect connect)
        {
            string msg = "";
            try
            {
                //if (socket.Connected)
                //{
                //    socket.Close();
                //}
                //检测socket是否连接
                //设置超时时间为10秒

                if (!socket.Connected)
                {
                    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    socket.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
                    socket.ReceiveTimeout = 10000;
                }
                if (!socket.Connected)
                {
                    msg = "未连接到socket服务端，请检查是否启动";
                    return msg;
                }
                //发送基础数据
                int status = 0;
                status = socket.Send(connect.getConnect());

                //if (isFirst)
                //{
                //    status = socket.Send(Connect.getIo());
                //    isFirst = false;
                //}
            }
            catch (Exception e)
            {
                LogUtils.WriteLog(e.Message);
                MessageBox.Show("连接主机异常：" + e.Message);
                msg = e.Message;
            }
            return msg;

        }

        //DAC
        public static string SendDac(Connect connect)
        {
            string msg = "";
            try
            {
                //if (socket.Connected)
                //{
                //    socket.Close();
                //}
                //检测socket是否连接
                //设置超时时间为10秒

                if (!socket.Connected)
                {
                    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    socket.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
                    socket.ReceiveTimeout = 10000;
                }
                if (!socket.Connected)
                {
                    msg = "未连接到socket服务端，请检查是否启动";
                    return msg;
                }
                //发送基础数据
                UInt16[] ushortArray = new UInt16[640];
                ushortArray[0] = 0x0A05;
                ushortArray[1] = 0x0A0A;
                ushortArray[2] = connect.U2_ChannelNum;
                if (connect.DAC.Length!=512)
                {
                    msg = "DAC点数异常";
                    return msg;
                }
                for(int i=0;i< connect.DAC.Length; i++)
                {
                    ushortArray[3+i] = (ushort)connect.DAC[i];
                }
                byte[] byteArray = new byte[ushortArray.Length * sizeof(ushort)];
                Buffer.BlockCopy(ushortArray, 0, byteArray, 0, byteArray.Length);
                int status = socket.Send(byteArray);

                //if (isFirst)
                //{
                //    status = socket.Send(Connect.getIo());
                //    isFirst = false;
                //}
            }
            catch (Exception e)
            {
                LogUtils.WriteLog(e.Message);
                MessageBox.Show("连接主机异常：" + e.Message);
                msg = e.Message;
            }
            return msg;

        }

        //TCG
        public static string SendTCG(Connect connect)
        {
            string msg = "";
            try
            {
                //if (socket.Connected)
                //{
                //    socket.Close();
                //}
                //检测socket是否连接
                //设置超时时间为10秒

                if (!socket.Connected)
                {
                    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    socket.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
                    socket.ReceiveTimeout = 10000;
                }
                if (!socket.Connected)
                {
                    msg = "未连接到socket服务端，请检查是否启动";
                    return msg;
                }

                //发送基础数据
                UInt16[] ushortArray = new UInt16[50];
                ushortArray[0] = 0x0A05;
                ushortArray[1] = 0x50A0;
                ushortArray[2] = connect.U2_ChannelNum;
                if (connect.TCG.Count > 10)
                {
                    msg = "TCG点数异常";
                    return msg;
                }
                for (int i = 0; i < connect.TCG.Count; i++)
                {
                    float[] temp = connect.TCG[i];
                    ushortArray[3 + i * 4] = (ushort)temp[0];
                    ushortArray[3 + i * 4 + 1] = (ushort)(temp[1]*10);
                    ushortArray[3 + i * 4 + 2] = (ushort)temp[2];
                    ushortArray[3 + i * 4 + 3] = (ushort)temp[3];
                }
                //ushortArray[connect.TCG.Count * 4 + 3] = 10000;
                //ushortArray[connect.TCG.Count * 4 + 4] = ushortArray[connect.TCG.Count * 4];
                //ushortArray[connect.TCG.Count * 4 + 5] = 0;
                //ushortArray[connect.TCG.Count * 4 + 6] = 46;
                //ushortArray[44] = 256;
                //ushortArray[45] = 256;
                //ushortArray[46] = 256;
                //ushortArray[47] = 3855;
                //ushortArray[48] = 3855;
                byte[] byteArray = new byte[ushortArray.Length * sizeof(ushort)];
                Buffer.BlockCopy(ushortArray, 0, byteArray, 0, byteArray.Length);
                int status = socket.Send(byteArray);
            }
            catch (Exception e)
            {
                LogUtils.WriteLog(e.Message);
                MessageBox.Show("连接主机异常：" + e.Message);
                msg = e.Message;
            }
            return msg;

        }
        static List<byte[]> test = new List<byte[]>();
        static List<int> test2 = new List<int>();
        private static void ReceiveData()
        {
            while (isRunning)
            {
                try
                {
                    byte[] buffer = new byte[1280];
                    int received = 0;
                    while (received < 1280)
                    {
                        int bytes = socket.Receive(buffer, received, 1280 - received, SocketFlags.None);
                        //if (bytes == 0) throw new SocketException(); // 连接断开
                        received += bytes;
                    }
                    dataAORC = buffer;

                    
                    //处理A扫与C扫
                    setDataAAndC(dataAORC);
                }
                catch (Exception ex)
                {
                    LogUtils.WriteLog(ex.Message);
                    //MessageBox.Show(ex.Message);
                    isRunning = false;
                }
            }
        }

        private static void setDataAAndC(byte[] dataAORC_)
        {
            if (dataAORC_ == null)
            {
                return;
            }
            if (dataAORC_[5] == 10 && dataAORC_[6] == 10)
            {
                DataAandC dataA = new DataAandC();
                SocketUtils.getDataA(dataA, dataAORC_);
                int index = dataA.U8_ChannelNum;
                AcqData.dataAs[index] = dataA;
                AcqData.AddDataA(index, dataA);
            }
            else if (dataAORC_[5] == 85 && dataAORC_[6] == 85)
            {
                DataCDetail dataC = new DataCDetail();
                SocketUtils.getDataC(dataC, dataAORC_);
                int index = dataC.U8_ChannelNum;
                AcqData.AddDataC1(index,dataC.U10_DataC);
            }
            else
            {
                //LogUtils.WriteLog(data[5].ToString());
            }
        }

        public static void getDataA(DataAandC dataA,byte[] source)
        {
            if (source == null || source.Length < 1024)
                throw new ArgumentException("source 长度不足或为空");
            double[] doubles = new double[512];
            for(int i=0;i< doubles.Length; i ++)
            {
                doubles[i] = ((source[10 + i * 2 +1] << 8) | source[10+i*2])*100/ HEIGHT_VAL;
            }
            dataA.U10_DataA = doubles;
            dataA.U8_ChannelNum = source[8];
            dataA.U1034_CH_DR0_VIEW_FIRST = byte2Int16(source[1034], source[1035]);
            dataA.U1036_CH_DR0_VIEW_LAST = byte2Int16(source[1036], source[1037]);
            dataA.U1038_CH_DR0_CROSS_POS = byte2Int16(source[1038], source[1039]);
            dataA.U1040_CH_DR0_CROSS_VAL = byte2Int16(source[1040], source[1041]) * 100 / HEIGHT_VAL;
            dataA.U1042_CH_DR0_MAX_POS = byte2Int16(source[1042], source[1043]);
            dataA.U1044_CH_DR0_MAX_VAL = byte2Int16(source[1044], source[1045]) * 100 / HEIGHT_VAL;
            dataA.U1046_CH_DR0_CROSS = byte2Int16(source[1146], source[1047]);
            dataA.U1048_CH_DR1_VIEW_FIRST = byte2Int16(source[1048], source[1049]);
            dataA.U1050_CH_DR1_VIEW_LAST = byte2Int16(source[1050], source[1051]);
            dataA.U1052_CH_DR1_CROSS_POS = byte2Int16(source[1052], source[1053]);
            dataA.U1054_CH_DR1_CROSS_VAL = byte2Int16(source[1054], source[1055]) * 100 / HEIGHT_VAL;
            dataA.U1056_CH_DR1_MAX_POS = byte2Int16(source[1056], source[1057]);
            dataA.U1058_CH_DR1_MAX_VAL = byte2Int16(source[1058], source[1059]) * 100 / HEIGHT_VAL;
            dataA.U1060_CH_DR1_CROSS = byte2Int16(source[1060], source[1061]);
            dataA.U1062_CH_DR2_VIEW_FIRST = byte2Int16(source[1062], source[1063]);
            dataA.U1064_CH_DR2_VIEW_LAST = byte2Int16(source[1064], source[1065]);
            dataA.U1066_CH_DR2_CROSS_POS = byte2Int16(source[1066], source[1067]);
            dataA.U1068_CH_DR2_CROSS_VAL = byte2Int16(source[1068], source[1069])*100 / HEIGHT_VAL;
            dataA.U1070_CH_DR2_MAX_POS = byte2Int16(source[1070], source[1071]);
            dataA.U1072_CH_DR2_MAX_VAL = byte2Int16(source[1072], source[1073])*100 / HEIGHT_VAL;
            dataA.U1074_CH_DR2_CROSS = byte2Int16(source[1074], source[1075]);
            dataA.U1076_CH_NUM_FIFO = byte2Int16(source[1076], source[1077]);
            dataA.U1078_CH_CSCAN = byte2Int16(source[1078], source[1079]);
            dataA.U1080_MAX_DR0_MAX_VAL = byte2Int16(source[1080], source[1081]);
            dataA.U1082_MIN_DR0_MAX_VAL = byte2Int16(source[1082], source[1083]);
            dataA.U1084_MAX_DR0_MAX_POS = byte2Int16(source[1084], source[1085]);
            dataA.U1086_MIN_DR0_MAX_POS = byte2Int16(source[1086], source[1087]);
            dataA.U1088_MAX_DR0_CROSS_POS = byte2Int16(source[1088], source[1089]);
            dataA.U1090_MIN_DR0_CROSS_POS = byte2Int16(source[1090], source[1091]);
            dataA.U1092_MAX_DR1_MAX_VAL = byte2Int16(source[1092], source[1093]);
            dataA.U1094_MIN_DR1_MAX_VAL = byte2Int16(source[1094], source[1095]);
            dataA.U1096_MAX_DR1_MAX_POS = byte2Int16(source[1096], source[1097]);
            dataA.U1098_MIN_DR1_MAX_POS = byte2Int16(source[1098], source[1099]);
            dataA.U1100_MAX_DR1_CROSS_POS = byte2Int16(source[1100], source[1101]);
            dataA.U1102_MIN_DR1_CROSS_POS = byte2Int16(source[1102], source[1103]);
            dataA.U1104_MAX_DR2_MAX_VAL = byte2Int16(source[1104], source[1105]);
            dataA.U1106_MIN_DR2_MAX_VAL = byte2Int16(source[1106], source[1107]);
            dataA.U1108_MAX_DR2_MAX_POS = byte2Int16(source[1108], source[1109]);
            dataA.U1110_MIN_DR2_MAX_POS = byte2Int16(source[1110], source[1111]);
            dataA.U1112_MAX_DR2_CROSS_POS = byte2Int16(source[1112], source[1113]);
            dataA.U1114_MIN_DR2_CROSS_POS = byte2Int16(source[1114], source[1115]);

            dataA.U1130_Encode0 = byte2Int32(source[1140], source[1141], source[1142], source[1143]);
            //dataA.U1132_Encode0H = byte2Int16(source[1132], source[1133]);
            dataA.U1134_Encode1 = byte2Int32(source[1144], source[1145], source[1146], source[1147]);
            //dataA.U1136_Encode1H = byte2Int16(source[1136], source[1137]);
        }
        internal static void CloseResources()
        {
            isFirst = true;
            isRunning = false;
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
        }
        internal static int byte2Int16(byte b1,byte b2)
        {
            int a = b2*16*16+b1;
            return a;
        }
        internal static int byte2Int32(byte b1, byte b2, byte b3, byte b4)
        {
            int a = BitConverter.ToInt32(new byte[]{b1,b2,b3,b4 }, 0);
            return a;
        }

        internal static void getDataC(DataCDetail dataC, byte[] source)
        {
            if (source == null || source.Length < 1024)
                throw new ArgumentException("source 长度不足或为空");
            dataC.U8_ChannelNum = source[8];
            dataC.U9_GroupNum = source[9];
            int index_ = 10;
            double[][] data = new double[dataC.U9_GroupNum][];
            for(int i = 0; i < dataC.U9_GroupNum; i++)
            {
                int index = index_ + i * 32;
                data[i] = new double[32];
                for (int j = 0; j < 32; j++)
                {
                    data[i][j] = source[index+j];
                }
            }
            dataC.U10_DataC = data;
        }
    }
}
